<?php
class drawer_svg{
 private $margin_left=5;
 private $margin_top=5;

 private $r_circle;
 private $s_square;
 private $l_rect;
 private $L_rect;
 private $l_elipse;
 private $h_elipse;
 private $array_color=array('#ff0000', '#ff5500', '#ffaa00', '#ffff00',
                            '#aaff00', '#55ff00', '#00ff00',
                            '#00ff55', '#00ffaa', '#00ffff',
                            '#55ffff', '#aaffff', '#ffffff');

 private $tool_color;

 private $x_tree_space=6;                //6
 private $y_tree_space=24;               //24
 private $r_tree_circle=6;               //6
 private $font1=11;

 public function __construct(){
  $this->tool_color=new tool_color();
 }

 public function __set_x_tree_space($_x){
  $this->x_tree_space=$_x;
 }
 public function __set_y_tree_space($_y){
  $this->y_tree_space=$_y;
 }
 public function __set_r_tree_circle($_c){
  $this->r_tree_circle=$_c;
 }
 public function __set_font1($_f){
  $this->font1=$_f;
 }

 public function dsvg_get_width($_tree){
  $nb_fils=0;
  $cpt=0;
  foreach($_tree->__get_array_tree() as $son){
   $cpt+=$this->dsvg_get_width($son);
   $nb_fils++;
  }
  if($nb_fils==0){
    $cpt=$this->r_tree_circle*2+$this->x_tree_space;
  }
  return $cpt;
 }

 public function dsvg_tree_get_html_height($_tree){
  return $_tree->__get_height()*$this->y_tree_space;
 }

 public function dsvg_tree_get_html_width($_tree){
  $res=$this->dsvg_get_width($_tree);
  return $res+$this->margin_left*3;
 }

 public function dsvg_forest_get_html_height($_forest){
  $array_tree=$_forest->__get_array_root();
  $max=1;
  foreach($array_tree as $tree){
    $h=$tree->__get_height();
    if($h>$max) $max=$h;
  }
  return $max*$this->y_tree_space;
 }

 public function dsvg_forest_get_html_width($_forest){
//  print_r($_forest);
  $array_tree=$_forest->__get_array_root();
  $w=0;
  foreach($array_tree as $tree){
    $w+=$this->dsvg_get_width($tree)+$this->margin_left*2;
  }
  if($w==0){
    $w=$this->r_tree_circle*2+$this->x_tree_space*2+$this->margin_left*2;
  }
  return $w+$this->margin_left*2;
 }

 public function dsvg_tree_defs(){
  $hr1=round($this->y_tree_space/2,0)-$this->r_tree_circle;
  $defs="
   <defs>
    <circle r=\"$this->r_tree_circle\" stroke=\"black\" id=\"c1\" />
    <rect width=\"0.5\" height=\"$hr1\" stroke=\"black\" id=\"r1\" />
   </defs>
  ";
  return $defs;
 }

 public function dsvg_forest_factory(){

 }

/*
  option:
    ["print"]=color|numeric|numeric_group|
    ["color_deep"]=null
    ["color_value"]=null
    ["numeric"]=null
    ["numeric_group"]=array_groupe
*/
 public function dsvg_tree_factory($_tree,$_option){
  $defs=$this->dsvg_tree_defs();
  $margin_left=$_cx=null;
  $deep=0;
  $res=self::dsvg_tree_factory_aux($_tree,$margin_left,$cx,$deep,$_option);
  return $defs.$res; 
 }

 public function dsvg_tree_factory_aux($_tree,$_margin_left,$_cx,$_deep,$_option){
  if($_margin_left==null)$_margin_left=$this->margin_left;

  //DEBUG à vérifier
  $pcircle = "";

  $deep=$_deep*$this->y_tree_space+$this->margin_top+$this->r_tree_circle;
  $half_deep=$deep+round($this->y_tree_space/2,0);
  $old_margin_left=$_margin_left;
  $deeppp=$deep+$this->y_tree_space;
  $deeppp_less_r=$deeppp-$this->r_tree_circle;
  $deep_and_r=$deep+$this->r_tree_circle;
  $first_cx=null;
  foreach($_tree->__get_array_tree() as $son){
   //$curent_margin_max=$this->dsvg_get_width($son)+$_margin_left;
   $curent_margin_max=$this->dsvg_get_width($son);
   $curent_cx=round(($curent_margin_max)/2,0)+$_margin_left;
   $pcircle.=$this->dsvg_tree_factory_aux($son,$_margin_left,$curent_cx,$_deep+1,$_option);
   $pcircle.="<use xlink:href=\"#r1\" x=\"$curent_cx\" y=\"$half_deep\" />\n";
   if($first_cx==null){$first_cx=$curent_cx;}
   $_margin_left+=$this->dsvg_get_width($son);
  }
  $cpt_son=count($_tree->__get_array_tree());
  if($first_cx==null){
    $first_cx=$_margin_left+$this->x_tree_space+$this->r_tree_circle;
    $curent_cx=$first_cx;
  }
  if($_cx==null) $_cx=round(($curent_cx-$first_cx)/2,0)+$first_cx;

  switch($_option["print"]){
    case "color_deep":
      $color=$this->array_color[$_deep];
      $pcircle.="<use xlink:href=\"#c1\" x=\"$_cx\" y=\"$deep\" fill=\"$color\"/>";
      break;
    case "color_value":
      $id_color=$_tree->__get_value();
      $color=$this->tool_color->__get_color($id_color);
      $pcircle.="<use xlink:href=\"#c1\" x=\"$_cx\" y=\"$deep\" fill=\"$color\"/>";
      break;
    case "numeric":
      $ncx=$_cx-3; $ndeep=$deep+4;
      $pcircle.="<text x=\"$ncx\" y=\"$ndeep\" font-size=\"$this->font1\" fill=\"black\">".$_tree->__get_value()."</text>";
      break;
    case "color_group":
      $id_color=$_tree->__get_value();
      $true_id_color=$_option["color_group"][$id_color];
      $color=$this->tool_color->__get_color($true_id_color+1);
      $pcircle.="<use xlink:href=\"#c1\" x=\"$_cx\" y=\"$deep\" fill=\"$color\"/>";
      break;
    default:
      $color=$this->tool_color->__get_color($_deep);
      $pcircle.="<use xlink:href=\"#c1\" x=\"$_cx\" y=\"$deep\" fill=\"$color\"/>";
      break;
  }

  if($first_cx!=$curent_cx and $curent_cx!=null)
    $pcircle.="<line x1=\"$first_cx\" y1=\"$half_deep\" x2=\"$curent_cx\" y2=\"$half_deep\" stroke=\"black\" />\n";
  if($cpt_son>0)
    $pcircle.="<use xlink:href=\"#r1\" x=\"$_cx\" y=\"$deep_and_r\" />\n";
  return $pcircle;

 }

 public function dsvg_tree_draw($_tree){
  $defs=$this->dsvg_tree_defs();
  $margin_left=$_cx=null;
  $deep=0;
  $options = array('print'=>'color_deep');
  $res = self::dsvg_tree_factory_aux($_tree,$margin_left,$cx,$deep,$options);
  return $defs.$res; 
 }

 public function dsvg_forest_draw($_forest,$_option=array()){
  $defs=$this->dsvg_tree_defs();
  $pcircle="";
  $array_tree=$_forest->__get_array_root();
  $w=$this->margin_left;
  $array_parent=array();
  $array_parent[]=1;
  $max_height=$cpt=0;
  foreach($array_tree as $id=>$tree){
    ++$cpt;
    $pcircle.=$this->dsvg_tree_factory_aux($tree,$w,null,0,$_option);
    $w+=$this->dsvg_tree_get_html_width($tree);
    $h=$this->dsvg_tree_get_html_height($tree);
    if($max_height<$h) $max_height=$h;
    $array_parent[]=$w-$this->margin_left;
  }
  if($cpt==0){
    $max_height=$this->y_tree_space;
    $array_parent[]=$this->r_tree_circle*2+$this->x_tree_space*2+$w*2;
  }

  $count=count($array_parent);
  $max_height--;
  foreach($array_parent as $id=>$x){
    if($id==0){
      $pcircle.=self::dsvg_rect($x,1,0.5,$max_height);
      $pcircle.=self::dsvg_parenthese_tiret1($x,$max_height,$w=4);
    }
    elseif($id==$count-1){
      $pcircle.=self::dsvg_rect($x,1,0.5,$max_height);
      $pcircle.=self::dsvg_parenthese_tiret1($x-4,$max_height,$w=4);
    }
    else{
      $pcircle.=self::dsvg_parenthese_tiret1($x-4,$max_height,$w=3);
      $pcircle.=self::dsvg_rect($x-1,1,0.5,$max_height);
      $pcircle.=self::dsvg_parenthese_tiret1($x+2,$max_height,$w=3);
      $pcircle.=self::dsvg_rect($x+2,1,0.5,$max_height);
    }
  }

  $res="$defs\n$pcircle";
  return $res;
 }

 private function dsvg_parenthese_tiret1($_x,$_y,$_w){
  return self::dsvg_rect($_x,1,$_w,0.5).self::dsvg_rect($_x,$_y,$_w,0.5);
 }

 private function dsvg_rect($_x,$_y,$_w,$_h){
  return "
      <rect x=\"$_x\" y=\"$_y\" width=\"$_w\" height=\"$_h\"
           fill=\"#FF0000\" fill-opacity=\"1\" stroke=\"#FF0000\" />
  ";
 }

 private function dsvg_forest_draw_aux2($_x,$_h){
  return "
     <rect x=\"$_x\" y=\"1\" width=\"0.5\" height=\"$_h\"
           fill=\"#FF0000\" fill-opacity=\"1\" stroke=\"#FF0000\" />";
 }

 public function dsvg_tree_group_numeric_draw($_tree,$_group){
  $res=$this->dsvg_tree_defs().$this->dsvg_tree_group_numeric_draw_aux($_tree,null,null,0,$_group);
  return $res;
 }

 public function dsvg_tree_group_numeric_draw_aux($_tree,$_margin_left=null,$_cx=null,$_deep,$_group=array()){
  if($_margin_left==null)
    $_margin_left=$this->margin_left-($this->r_tree_circle/2);

  $deep=$_deep*$this->y_tree_space+$this->margin_top+$this->r_tree_circle;
  $half_deep=$deep+round($this->y_tree_space/2,0);
  $old_margin_left=$_margin_left;
  $deeppp=$deep+$this->y_tree_space;
  $deeppp_less_r=$deeppp-$this->r_tree_circle;
  $deep_and_r=$deep+$this->r_tree_circle;
//  $color=$this->array_color[$_deep];
  $first_cx=null;
  foreach($_tree->__get_array_tree() as $son){
   $curent_margin_max=$this->dsvg_get_width($son)+$_margin_left;
   $curent_cx=round(($curent_margin_max-$_margin_left)/2,0)+$_margin_left;
   $pcircle.=$this->dsvg_tree_group_numeric_draw_aux($son,$_margin_left,$curent_cx,$_deep+1,$_group);
   $pcircle.="<use xlink:href=\"#r1\" x=\"$curent_cx\" y=\"$half_deep\" />\n";
   if($first_cx==null){$first_cx=$curent_cx;}
   $_margin_left+=$this->dsvg_get_width($son)+$this->x_tree_space;
  }
  $cpt_son=count($_tree->__get_array_tree());
  if($_cx==null) $_cx=round(($curent_cx-$first_cx)/2,0)+$first_cx;
  $ncx=$_cx-4; $ndeep=$deep+4;
  $rect_group_x=$ncx-2;
  $rect_group_y=$deep-6;
  $rect_group_width = (strlen($_tree->__get_value()."") > 1) ? 16 : 14;
  $rect_group_height=14;
  $id_color=$_group[$_tree->__get_value()];
  $rect_color=$this->tool_color->__get_color($id_color+1);
  if($id_color>0){
   $pcircle.="
     <rect x=\"$rect_group_x\" y=\"$rect_group_y\"
           width=\"$rect_group_width\" height=\"$rect_group_height\"
           fill=\"$rect_color\" fill-opacity=\"0.6\" stroke=\"#2222FF\" />
   ";
  }
  $pcircle.="<text x=\"$ncx\" y=\"$ndeep\" font-size=\"11\" fill=\"black\">".$_tree->__get_value()."</text>";
  if($first_cx!=$curent_cx and $curent_cx!=null)
    $pcircle.="<line x1=\"$first_cx\" y1=\"$half_deep\" x2=\"$curent_cx\" y2=\"$half_deep\" stroke=\"black\" />\n";
  if($cpt_son>0)
    $pcircle.="<use xlink:href=\"#r1\" x=\"$_cx\" y=\"$deep_and_r\" />\n";
  return $pcircle;
 }

 public function dsvg_tree_group_draw($_tree){
  $res=$this->dsvg_tree_defs().$this->dsvg_tree_group_numeric_draw_aux($_tree,null,null,0);
  return $res;
 }

 public function dsvg_tree_numeric_draw_aux($_tree,$_margin_left=null,$_cx=null,$_deep=0){
  if($_margin_left==null)$_margin_left=$this->margin_left;

  $deep=$_deep*$this->y_tree_space+$this->margin_top+$this->r_tree_circle;
  $half_deep=$deep+round($this->y_tree_space/2,0);
  $old_margin_left=$_margin_left;
  $deeppp=$deep+$this->y_tree_space;
  $deeppp_less_r=$deeppp-$this->r_tree_circle;
  $deep_and_r=$deep+$this->r_tree_circle;
  $color=$this->array_color[$_deep];
  $first_cx=null;
  foreach($_tree->__get_array_tree() as $son){
   $curent_margin_max=$this->dsvg_get_width($son)+$_margin_left;
   $curent_cx=round(($curent_margin_max-$_margin_left)/2,0)+$_margin_left;
   $pcircle.=$this->dsvg_tree_numeric_draw_aux($son,$_margin_left,$curent_cx,$_deep+1);
   $pcircle.="<use xlink:href=\"#r1\" x=\"$curent_cx\" y=\"$half_deep\" />\n";
   if($first_cx==null){$first_cx=$curent_cx;}
   $_margin_left+=$this->dsvg_get_width($son)+$this->x_tree_space;
  }
  $cpt_son=count($_tree->__get_array_tree());
  if($first_cx==null){
    $first_cx=$_margin_left+$this->x_tree_space+$this->r_tree_circle;
    $curent_cx=$first_cx;
  }
  if($_cx==null) $_cx=round(($curent_cx-$first_cx)/2,0)+$first_cx;
  $ncx=$_cx-3; $ndeep=$deep+4;
  $pcircle.="<text x=\"$ncx\" y=\"$ndeep\" font-size=\"$this->font1\" fill=\"black\">".$_tree->__get_value()."</text>";
  if($first_cx!=$curent_cx and $curent_cx!=null)
    $pcircle.="<line x1=\"$first_cx\" y1=\"$half_deep\" x2=\"$curent_cx\" y2=\"$half_deep\" stroke=\"black\" />\n";
  if($cpt_son>0)
    $pcircle.="<use xlink:href=\"#r1\" x=\"$_cx\" y=\"$deep_and_r\" />\n";//$pcircle.="<line x1=\"$_cx\" y1=\"$deep_and_r\" x2=\"$_cx\" y2=\"$half_deep\" stroke=\"black\"/>\n";
  return $pcircle;
 }

 public function dsvg_tree_idraw_structure($_tree,$_margin_left=null,$_cx=null,$_deep=0,$_id_circle=0){
  if($_margin_left==null)$_margin_left=$this->margin_left;
  $deep=$_deep*$this->y_tree_space+$this->margin_top+$this->r_tree_circle;
  $half_deep=$deep+round($this->y_tree_space/2,0);
  $old_margin_left=$_margin_left;
  $deeppp=$deep+$this->y_tree_space;
  $deeppp_less_r=$deeppp-$this->r_tree_circle;
  $deep_and_r=$deep+$this->r_tree_circle;
  $color=$this->array_color[$_deep];
  $first_cx=null;
  foreach($_tree->__get_array_tree() as $id_son=>$son){
   $curent_margin_max=$this->dsvg_get_width($son)+$_margin_left;
   $curent_cx=round(($curent_margin_max-$_margin_left)/2,0)+$_margin_left;
   $pcircle.=$this->dsvg_tree_idraw_structure($son,$_margin_left,$curent_cx,$_deep+1,$_id_circle."_".$id_son);
   $pcircle.="<line x1=\"$curent_cx\" y1=\"$half_deep\" x2=\"$curent_cx\" y2=\"$deeppp_less_r\" stroke=\"black\"/>\n";
   if($first_cx==null){$first_cx=$curent_cx;}
   $_margin_left+=$this->dsvg_get_width($son)+$this->x_tree_space;
   $_y_cpt++;
  }
  $cpt_son=count($_tree->__get_array_tree());
  if($_cx==null){$_cx=round(($curent_cx-$first_cx)/2,0)+$first_cx;}
  $pcircle.="<circle id=\"circle$_id_circle\"
   onmouseover=\"change_style('circle$_id_circle','fill:#FFFFFF;stroke:blue;');change_style2('bloc$_id_circle','font-size:110%;color:blue;');\$pulsate('bloc$_id_circle',1,250);\"
   onmouseout=\"change_style('circle$_id_circle','fill:$color;stroke:blue;');change_style2('bloc$_id_circle','font-size:100%;color:black;');\"
   cx=\"$_cx\" cy=\"$deep\" r=\"$this->r_tree_circle\" style=\"fill:$color;stroke:black\"/>";
  $pcircle.="<line x1=\"$first_cx\" y1=\"$half_deep\" x2=\"$curent_cx\" y2=\"$half_deep\" stroke=\"black\"/>\n";
  if($cpt_son>0)
   $pcircle.="<line x1=\"$_cx\" y1=\"$deep_and_r\" x2=\"$_cx\" y2=\"$half_deep\" stroke=\"black\"/>\n";
  return $pcircle;
 }
}

/*
 public function dsvg_tree_draw_aux($_tree,$_margin_left=null,$_cx=null,$_deep=0){
  if($_margin_left==null)$_margin_left=$this->margin_left;
  $pcircle = "";

  $deep=$_deep*$this->y_tree_space+$this->margin_top+$this->r_tree_circle;
  $half_deep=$deep+round($this->y_tree_space/2,0);
  $old_margin_left=$_margin_left;
  $deep_and_r=$deep+$this->r_tree_circle;
  $color=$this->array_color[$_deep];
  $first_cx=null;
  foreach($_tree->__get_array_tree() as $son){
    $curent_margin_max=$this->dsvg_get_width($son)+$_margin_left;
    $curent_cx=round(($curent_margin_max-$_margin_left)/2,0)+$_margin_left;
    $pcircle.=$this->dsvg_tree_draw_aux($son,$_margin_left,$curent_cx,$_deep+1);
    $pcircle.="<use xlink:href=\"#r1\" x=\"$curent_cx\" y=\"$half_deep\" />\n";
    if($first_cx==null){$first_cx=$curent_cx;}
    $_margin_left+=$this->dsvg_get_width($son)+$this->x_tree_space;
  }
  if($_cx==null){
    $_cx=round(($curent_cx-$first_cx)/2,0)+$first_cx;  //+$old_margin_left
  }
  $pcircle.="<use xlink:href=\"#c1\" x=\"$_cx\" y=\"$deep\" fill=\"$color\"/>";
  if(isset($curent_cx) and $first_cx != $curent_cx and $curent_cx != NULL){
      $pcircle .= "
        <line x1=\"$first_cx\" y1=\"$half_deep\"
              x2=\"$curent_cx\" y2=\"$half_deep\" stroke=\"black\"/>\n
      ";
    }
  if(count($_tree->__get_array_tree())>0)
    $pcircle.="<use xlink:href=\"#r1\" x=\"$_cx\" y=\"$deep_and_r\" />\n";
  return $pcircle;
 }
*/

/*

 public function dsvg_tree_draw_aux($_tree,$_margin_left=null,$_cx=null,$_deep=0){
  if($_margin_left==null)$_margin_left=$this->margin_left;

  $deep=$_deep*$this->y_tree_space+$this->margin_top+$this->r_tree_circle;
  $half_deep=$deep+round($this->y_tree_space/2,0);
  $old_margin_left=$_margin_left;
  $deeppp=$deep+$this->y_tree_space;
  $deeppp_less_r=$deeppp-$this->r_tree_circle;
  $deep_and_r=$deep+$this->r_tree_circle;
  $color=$this->array_color[$_deep];
  $first_cx=null;
  foreach($_tree->__get_array_tree() as $son){
   $curent_margin_max=$this->dsvg_get_width($son)+$_margin_left;
   $curent_cx=round(($curent_margin_max-$_margin_left)/2,0)+$_margin_left;
   $pcircle.=$this->dsvg_tree_draw_aux($son,$_margin_left,$curent_cx,$_deep+1);
   //$pcircle.="<line x1=\"$curent_cx\" y1=\"$half_deep\" x2=\"$curent_cx\" y2=\"$deeppp_less_r\" stroke=\"black\"/>\n";
   $pcircle.="<use xlink:href=\"#r1\" x=\"$curent_cx\" y=\"$half_deep\" />\n";
   if($first_cx==null){$first_cx=$curent_cx;}
   $_margin_left+=$this->dsvg_get_width($son)+$this->x_tree_space;
  }
  $cpt_son=count($_tree->__get_array_tree());
  if($_cx==null){$_cx=round(($curent_cx-$first_cx)/2,0)+$first_cx;}
  //$pcircle.="<circle cx=\"$_cx\" cy=\"$deep\" r=\"$this->r_tree_circle\" style=\"fill:$color;stroke:black\"/>";
  $pcircle.="<use xlink:href=\"#c1\" x=\"$_cx\" y=\"$deep\" fill=\"$color\"/>";
  $pcircle.="<line x1=\"$first_cx\" y1=\"$half_deep\" x2=\"$curent_cx\" y2=\"$half_deep\" stroke=\"black\"/>\n";
  if($cpt_son>0)
   $pcircle.="<use xlink:href=\"#r1\" x=\"$_cx\" y=\"$deep_and_r\" />\n";
   //$pcircle.="<line x1=\"$_cx\" y1=\"$deep_and_r\" x2=\"$_cx\" y2=\"$half_deep\" stroke=\"black\"/>\n";
  return $pcircle;
 }
*/
?>
